package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserFeignClient;
import com.atguigu.tingshu.vo.album.TrackInfoVo;
import com.atguigu.tingshu.vo.album.TrackListVo;
import com.atguigu.tingshu.vo.album.TrackMediaInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private TrackStatMapper trackStatMapper;

    @Autowired
    private VodService vodService;

    @Autowired
    private UserFeignClient userFeignClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTrackInfo(Long userId, TrackInfoVo trackInfoVo) {
        //保存声音
        TrackInfo trackInfo = BeanUtil.copyProperties(trackInfoVo, TrackInfo.class);
        trackInfo.setUserId(userId);
        trackInfo.setSource("1");
        trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
        trackInfo.setOrderNum(albumInfo.getIncludeTrackCount() + 1);

        //获取腾讯云上存储的图像id
        TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
        if(trackMediaInfoVo != null){
            trackInfo.setMediaType(trackMediaInfoVo.getType());
            trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
            trackInfo.setMediaSize(trackMediaInfoVo.getSize());
        }
        trackInfoMapper.insert(trackInfo);
        Long trackdId = trackInfo.getId();

        //新增声音统计表
        addTrackStat(trackdId, SystemConstant.TRACK_STAT_PLAY,0);
        addTrackStat(trackdId, SystemConstant.TRACK_STAT_COLLECT,0);
        addTrackStat(trackdId, SystemConstant.TRACK_STAT_PRAISE,0);
        addTrackStat(trackdId, SystemConstant.TRACK_STAT_COMMENT,0);

        //增加专辑下的声音数量
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() + 1);
        albumInfoMapper.updateById(albumInfo);
    }

    /**
     * 获取当前用户声音分页列表
     * @param Page
     * @param trackInfoQuery
     * @return
     */
    @Override
    public Page<TrackListVo> getTrackStatVo(Page<TrackListVo> Page, TrackInfoQuery trackInfoQuery) {
        return trackInfoMapper.selectTrackStatVo(Page, trackInfoQuery);
    }

    /**
     * 修改声音信息
     * @param trackId
     * @param trackInfoVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTrackInfo(Long trackId, TrackInfoVo trackInfoVo) {
        //更新声音
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        //初始音乐id
        String mediaFileIdBefore = trackInfo.getMediaFileId();
        //更新之后的id
        String mediaFileIdAfter = trackInfoVo.getMediaFileId();
        BeanUtils.copyProperties(trackInfoVo, trackInfo);
        if(!mediaFileIdBefore.equals(mediaFileIdAfter)){
            TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(mediaFileIdAfter);
            if(trackMediaInfoVo != null){
                trackInfo.setMediaType(trackMediaInfoVo.getType());
                trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
                trackInfo.setMediaSize(trackMediaInfoVo.getSize());
                //4.将变更前声音文件从云点播平台删除
                vodService.deleteTrackMedia(mediaFileIdBefore);
            }
        }
        //更新
        trackInfoMapper.updateById(trackInfo);

    }

    /**
     * 删除声音信息
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeTrackInfo(Long trackId) {
        //更新三个表
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        Integer orderNum = trackInfo.getOrderNum();
        String mediaFileId = trackInfo.getMediaFileId();
        //设置ordernum后面的顺序
        trackInfoMapper.updateOrderNum(trackInfo.getAlbumId(),orderNum);
        //删除声音
        vodService.deleteTrackMedia(mediaFileId);
        trackInfoMapper.deleteById(trackId);
        //删除统计表
        trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,trackId));
        //更新专辑声音总数
        AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
        albumInfo.setIncludeTrackCount(albumInfo.getIncludeTrackCount() - 1);
        albumInfoMapper.updateById(albumInfo);
    }

    /**
     * 更新声音统计
     * @param trackId
     * @param statType
     * @param count
     */
    @Override
    public void updateTrackStat(Long trackId, String statType, Integer count) {
        trackStatMapper.updateTrackStat(trackId, statType, count);
    }

    /**
     * 获取用户声音分集购买支付列表
     * @param trackId
     * @return
     */
    @Override
    public List<Map<String, Object>> findUserTrackPaidList(Long trackId) {
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, trackInfo.getAlbumId()).ge(TrackInfo::getOrderNum, trackInfo.getOrderNum());
        List<TrackInfo> waitBuyTrackList = trackInfoMapper.selectList(queryWrapper);

        List<Long> userPaidTrackIdList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();
        if (CollectionUtil.isNotEmpty(userPaidTrackIdList)){
            waitBuyTrackList.removeIf(waitTrackInfo -> userPaidTrackIdList.contains(waitTrackInfo.getId()));
        }

        List<Map<String, Object>> mapList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(waitBuyTrackList)){
            AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
            //获取原价
            BigDecimal price = albumInfo.getPrice();
            // 构建本集购买对象
            Map<String, Object> currMap = new HashMap<>();
            currMap.put("name", "本集");
            currMap.put("price", price);
            currMap.put("trackCount", 1);
            mapList.add(currMap);
            //构建集合
            int count = waitBuyTrackList.size();
            for (int i = 10; i <= 50 && count > 1; i+=10){
                //判断数量>i 固定显示后i集
                if (i < count && i < 50) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", "后" + i + "集");
                    map.put("price", price.multiply(new BigDecimal(i)));
                    map.put("trackCount", i);
                    mapList.add(map);
                } else {
                    //反之全集（动态构建后count集合）
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", "后" + count + "集");
                    map.put("price", price.multiply(new BigDecimal(count)));
                    map.put("trackCount", count);
                    mapList.add(map);
                    break;
                }
            }
        }

        return mapList;
    }

    /**
     * 根据声音ID和数量获取用户未购买的付费声音列表
     * 功能流程：
     * 1. 获取当前用户ID
     * 2. 查询起始声音信息
     * 3. 获取用户已购买的所有声音ID列表
     * 4. 构建查询条件：同一专辑且排序号大于等于当前声音
     * 5. 如果用户已购买过声音，则排除这些已购买的声音
     * 6. 限制返回结果数量
     * 7. 指定返回的声音信息字段
     * 
     * @param trackId 需要获取付费声音列表的起始声音ID
     * @param trackCount 需要获取的付费声音数量
     * @return List<TrackInfo> 符合条件的付费声音列表，包含声音ID、标题、封面和所属专辑ID信息
     */
    @Override
    public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount) {
        Long userId = AuthContextHolder.getUserId();
        TrackInfo trackInfo = trackInfoMapper.selectById(trackId);
        List<Long> userPaidTrackIdList = userFeignClient.findUserPaidTrackList(trackInfo.getAlbumId()).getData();
        
        // 构建查询条件：同一专辑且排序号大于等于当前track的
        LambdaQueryWrapper<TrackInfo> queryWrapper = new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId, trackInfo.getAlbumId()).ge(TrackInfo::getOrderNum, trackInfo.getOrderNum());
        
        // 如果用户已购买过某些声音，则在查询结果中排除这些已购买的声音
        if (CollectionUtil.isNotEmpty(userPaidTrackIdList)){
            queryWrapper.notIn(TrackInfo::getId, userPaidTrackIdList);
        }
        
        // 限制查询结果数量为需要获取的声音数量
        queryWrapper.last("limit " + trackCount.intValue());
        
        // 指定返回的声音信息字段：ID、标题、封面和所属专辑ID
        queryWrapper.select(TrackInfo::getId, TrackInfo::getTrackTitle, TrackInfo::getCoverUrl, TrackInfo::getAlbumId);
        List<TrackInfo> waitBuyTrackList = trackInfoMapper.selectList(queryWrapper);
        return waitBuyTrackList;
    }

    /**
     * 新增声音统计表
     * @param trackdId
     * @param statType
     * @param statNum
     */
    private void addTrackStat(Long trackdId, String statType, int statNum) {
        TrackStat trackStat = new TrackStat();
        trackStat.setTrackId(trackdId);
        trackStat.setStatType(statType);
        trackStat.setStatNum(statNum);
        trackStatMapper.insert(trackStat);
    }
}
